#include <stdio.h>
#include <linux/input.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>           
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <pthread.h>
#include <sys/select.h>

#include "share_common.h"

static int	 key_shutter_enable = 0;
static int	 photo_count = 0;


//static void date_init(void)


double get_dtime(void)
{
  struct timeval tv;

  gettimeofday(&tv, NULL);

  return ((double)(tv.tv_sec) + (double)(tv.tv_usec) * 0.001 * 0.001);
}

#if 0
struct event_status{
	int AF_status;
	int Shutter_status;
	int Cross_Center_status;

};

void INThandler(){
       exit(0);

}
#endif
#if 0
static void uvc_start(int start){
	if (start)
		system("camera_if_direct 0x8 0x2 0x1");
	else
		system("camera_if_direct 0x8 0x2 0x0");
}

static void Cross_Center_BTN_CB(int status){
        if(status){
                printf("cross_center pressed, start uvc-h264...\n");
                if ( access("/run/SD/mmcblk0p1/uvc264.sh", F_OK) != -1){ 
                        printf("uvc264.sh exists in sd card\n");
                        system("sh /run/SD/mmcblk0p1/uvc264.sh");
		}else{
			system("camera_if_direct 0x1 0x2 0x22");
                	sleep(1);
                	system("camera_if_direct 0x0 0xb 0x2");
                	sleep(1);
                	printf("start to run uvc\n");
                	sleep(1);
                	system("camera_if_direct 0x0 0xb 0x8");
		}
        }else{
                printf("Shutter pressed, stop uvc-h264\n");
		system("camera_if_direct 0xd 0x3 0x2");
		system("camera_if_direct 0x0 0xb 0x1");
        }
}
static void Shutter_BTN_CB(int status){
	//uvc_start(status);
	if(status){
		printf("Shutter pressed, start uvc-mjpeg...\n");

		if ( access("/run/SD/mmcblk0p1/uvcmjpeg.sh", F_OK) != -1){
			printf("uvcmjpeg.sh exists in sd card\n");
			system("sh /run/SD/mmcblk0p1/uvcmjpeg.sh");
		}else{
			printf("set res as 1280x720 \n");
			system("camera_if_direct 0x1 0xc 0x11"); //user_0_size = 1280x720
			sleep(1);
			system("camera_if_direct 0x0 0xb 0x2");
			sleep(1);
			uvc_start(status);
			printf("start to run uvc\n");
			//sleep(1);
			//system("camera_if_direct 0x0 0xb 0x7");
		}
	}else{
		printf("Shutter pressed, stop uvc-mjpeg\n");
		system("camera_if_direct 0x0 0xb 0x1");
		uvc_start(status);
	}
}

static void AF_BTN_CB(int status){
	if(status){
        	printf("AF pressed, start streaming\n");
		system("camera_if_direct 0x0 0x1 0x1");
		//system("camera_if_direct 0x0 0x6 0x00");
		//system("camera_if_direct 0x0 0x7 0xf");
		//system("camera_if_direct 0x0 0x8 0x70");
		//system("camera_if_direct 0x0 0x9 0x8");
		system("camera_if_direct 0x1 0xc 0x04");//user_0_size = 3840x2160
		system("camera_if_direct 0x0 0xa 0x0");
		system("camera_if_direct 0x0 0xb 0x2");
        }else{
                printf("AF pressed, stop streaming\n");
		system("camera_if_direct 0x0 0xb 0x1");
        }
	
}
#endif
//#define CAMERA_IDLE 1
//#define CAMERA_PREVIEW 1



static void start_boot_mode(int start){
	if (start == CAMERA_IDLE){
		system("camera_if_direct 0x0 0xb 0x1");
	}
	else if (start == CAMERA_PREVIEW){
		system("camera_if_direct 0x0 0xb 0x2");
	}
	else if (start == CAMERA_PHOTO){
		system("camera_if_direct 0x0 0xb 0x3");
	}
	else if (start == CAMERA_RECORD_START){
		system("camera_if_direct 0x0 0xb 0x8");
	}
	else if (start == CAMERA_RECORD_STOP){
		system("camera_if_direct 0x0 0xb 0x9");
	}
	else if (start == CAMERA_PHOTO_JPEG_RAW){
		system("camera_if_direct 0x0 0xb 0x4");
	}
	else if (start == CAMERA_VIEW_SHOT){
		system("camera_if_direct 0x0 0xb 0x7");
	}
	else{
		system("camera_if_direct 0x0 0xb 0x2");
	}
		
}
static void net_init(void)
{

	system("net_init");
	system("ifconfig eth0 192.168.31.20");
}
static void date_init(void)
{
    double d0, d1, d2, d3, d4;
    struct timeval tv[10];
    struct timespec ctv[10];
    struct timespec req, tp;
    int i;

    d0 = get_dtime();
    usleep(1000);
    d1 = get_dtime();
    usleep(10000);
    d2 = get_dtime();
    usleep(100000);
    d3 = get_dtime();
    sleep(1);
    d4 = get_dtime();

    printf("-----------------\n");
    printf("usleep 1000  : %f\n", d1 - d0);
    printf("usleep 10000 : %f\n", d2 - d1);
    printf("usleep 100000: %f\n", d3 - d2);
    printf(" sleep       : %f\n", d4 - d3);

    req.tv_sec  = 0;
    req.tv_nsec = 1000000; // 1ms

    for (i = 0; i < 10; i++) {
        nanosleep(&req, NULL);
        gettimeofday(tv + i, NULL);
    }

    printf("-----------------\n");
    for (i = 0; i < 10; i++) {
        printf("nanosleep %ld-%06ld\n", (long)tv[i].tv_sec, (long)tv[i].tv_usec);
    }

    req.tv_sec  = 0;
    req.tv_nsec = 1000000; // 1ms

    for (i = 0; i < 10; i++) {
        nanosleep(&req, NULL);
        clock_gettime(CLOCK_MONOTONIC, &tp);
        ctv[i].tv_sec  = tp.tv_sec;
        ctv[i].tv_nsec = tp.tv_nsec;
    }

    printf("-----------------\n");
    for (i = 0; i < 10; i++) {
        printf("MONOTONIC %ld %06ld\n", (long)ctv[i].tv_sec, (long)ctv[i].tv_nsec);
    }
 }


static pthread_t tid_monitor;
static pthread_t key_monitor;

static int h264_config(int h264_size,int camera_fps,int bitrate,int photo_size)
{

		system("camera_if_direct 0x1 0x2 0x22");  //使能h264�?        
		system("camera_if_direct 0x1 0x3 0x0");  //关闭音频�?        
		system("camera_if_direct 0x1 0x0c 0x0");  //使能 user_0_size  4000*3000
        system("camera_if_direct 0x1 0x0e 0xFFFFFFFF"); //关闭h265-size

        // camera size
        if(CAMERA_H264_SIZE_720P == h264_size){
                system("camera_if_direct 0x1 0x0f 0x11"); // 输出720p
        }
        if(CAMERA_H264_SIZE_1080P == h264_size){
                system("camera_if_direct 0x1 0x0f 0x0B"); // 输出1080p
        }

        // camera fps
        if(CAMERA_24FPS == camera_fps){
                system("camera_if_direct 0x1 0x12 0x13"); // 输出24fps
        }
        if(CAMERA_25FPS == camera_fps){
                system("camera_if_direct 0x1 0x12 0x12"); // 输出25fps
        }
        if(CAMERA_30FPS == camera_fps){
                system("camera_if_direct 0x1 0x12 0x11"); // 输出30fps
        }

        // camera_h264 bitrate 
        if(CAMERA_H264_BITRATE_1M == bitrate){
                system("camera_if_direct 0x1 0x19 0x1"); // 配置码率�?Mbps
        }
        if(CAMERA_H264_BITRATE_2M == bitrate){
                system("camera_if_direct 0x1 0x19 0x2"); // 配置码率�?Mbps
        }
        if(CAMERA_H264_BITRATE_4M == bitrate){
                system("camera_if_direct 0x1 0x19 0x4"); // 配置码率�?Mbps
        }
       
        // defalut :4000*3000
        
        if(CAMERA_PHOTO_SIZE_12M == photo_size){
                system("camera_if_direct 0xB 0x00 4000");
                system("camera_if_direct 0xB 0x01 3000");
        }else if(CAMERA_PHOTO_SIZE_2M == photo_size){
                system("camera_if_direct 0xB 0x00 1920");
                system("camera_if_direct 0xB 0x01 1080");
        }else if(CAMERA_PHOTO_SIZE_8M == photo_size){
                system("camera_if_direct 0xB 0x00 3840");
                system("camera_if_direct 0xB 0x01 2160");
        }else if(CAMERA_PHOTO_SIZE_26M == photo_size){
                system("camera_if_direct 0xB 0x00 6144");
                system("camera_if_direct 0xB 0x01 4096");
        }else{
                system("camera_if_direct 0xB 0x00 4000");
                system("camera_if_direct 0xB 0x01 3000");
        }
        return 0;
}
static int net_stream_start(void)
{
	system("sni-gstrtsp eth0 \"ipcusrc extend=TRUE playctrl=TRUE ! ipcudemux format=256 stream=0 ! h264parse ! rtph264pay pt=96 name=pay0 \" &");
        return 0;
}
static void* thread_capture(void* pVoid)
{
	int ret;
	printf("--------------- thread_RC !!! -----------------------------\n");
	while (1)
	{
                //printf("******************luke0043 start capture***********************\n");
		usleep(200*1000);
        //system("camera_if_direct 0x0 0xb 0x7");
        start_boot_mode(CAMERA_VIEW_SHOT);
		photo_count++;
		printf("--------------- photo_count=%d-----------------------------\n",photo_count);

		if(photo_count > 30000)
		{
			break;
		}


	}

	return NULL;
}
static void* thread_key_dectect(void* pVoid)
{
	int ret;
	FILE *fp;
	int data = 0;

	printf("--------------- thread_key_dectect !!! -----------------------------\n");




	system("echo 258 > /sys/class/gpio/export");
	
	while (1)
	{
		usleep(100*1000);
		
		fp = fopen("/sys/class/gpio/gpio258/value","r");
		if(fp == NULL) {
			printf("Error: /sys/class/gpio/gpio258/value file not open\n");
			return -1;
		}
		fscanf(fp, "%d", &data);
		fclose(fp);
        //printf("******************luke0043 start capture***********************\n");

		if((data == 1)&&(key_shutter_enable == 0)){
			data = 0;
			key_shutter_enable = 1;
		}

				
        //system("camera_if_direct 0x0 0xb 0x7");
        
	}

	return NULL;
}
int main(int argc, char *argv[])
{
	#if 0
        int fd;
	struct input_event ev;
	struct event_status *evs;

	evs = malloc(sizeof(struct event_status));
	evs->AF_status = 0;
	evs->Shutter_status = -1;
	evs->Cross_Center_status = -1;

	#endif
        int ret = 0;
		printf("******************luke0043 start***********************\n");

      //  fd = open("/dev/input/event0", O_RDWR, 0666);
      //  if (fd < 0)
      //          printf("input open error\n");
      //  else {
       //         signal(SIGINT, INThandler);
        //date_init();
        printf("******************luke0043 net init***********************\n");
        net_init();
		system_time_init();

        sleep(1);
        printf("******************luke0043 go to idle***********************\n");
        start_boot_mode(CAMERA_IDLE);
        sleep(1);


        printf("******************luke0043 start h264***********************\n");
        h264_config(CAMERA_H264_SIZE_720P,CAMERA_30FPS,CAMERA_H264_BITRATE_2M,CAMERA_PHOTO_SIZE_8M);

        printf("******************luke0043 go to preview***********************\n");
        start_boot_mode(CAMERA_PREVIEW);

        printf("******************luke0043 start rtsp***********************\n");
        net_stream_start();
        sleep(1);
       // printf("******************luke0043 start pthread***********************\n");
        //ret = pthread_create(&tid_monitor, NULL, thread_capture, 0);
		//ret = pthread_create(&key_monitor, NULL, thread_key_dectect, 0);
		
		
        if (ret != HI_SUCCESS)
        {
                printf("luke0043_Init, pthread_create thread_monitor error!\n");
                return HI_FAILURE;
        }

        while(1){

				//usleep(100*1000);

				if(key_shutter_enable)
				{
					key_shutter_enable = 0;
					printf("luke0043_key enter --------------------------\n");
        			start_boot_mode(CAMERA_VIEW_SHOT);
				}
		}

	return 0;
}
